package com.heima.homeservicemanagementsystem.controller;


import cn.dev33.satoken.annotation.SaIgnore;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradeFastpayRefundQueryModel;
import com.alipay.api.domain.AlipayTradeQueryModel;
import com.alipay.api.domain.AlipayTradeRefundModel;
import com.alipay.api.domain.AlipayTradeWapPayModel;
import com.alipay.api.request.*;
import com.alipay.api.response.AlipayTradeFastpayRefundQueryResponse;
import com.alipay.api.response.AlipayTradeQueryResponse;
import com.alipay.api.response.AlipayTradeRefundResponse;
import com.alipay.api.response.AlipayTradeWapPayResponse;
import com.alipay.easysdk.factory.Factory;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.heima.homeservicemanagementsystem.config.AlipayConfig;
import com.heima.homeservicemanagementsystem.config.annotation.RestControllerMapping;
import com.heima.homeservicemanagementsystem.entity.Apientity;
import com.heima.homeservicemanagementsystem.entity.BuyrOrder;
import com.heima.homeservicemanagementsystem.entity.common.OrderStatusEnum;
import com.heima.homeservicemanagementsystem.entity.vo.AlipayResponse;
import com.heima.homeservicemanagementsystem.module.Result;

import com.heima.homeservicemanagementsystem.service.BuyrOrderService;
import com.heima.homeservicemanagementsystem.service.impl.AliPayServiceImpl;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.json.Json;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static cn.dev33.satoken.SaManager.log;

/**
 * @Description
 * @Author jcf
 * @Date 2025/4/24
 */
@Tag(name = "支付相关接口")
@Slf4j
@RestControllerMapping("/pay")
public class AliPayController {

    @Resource
    private AlipayConfig aliPayConfig;
    @Resource
    private BuyrOrderService buyrOrderService;
    @Resource
    private AliPayServiceImpl aliPayService;

    //    @Resource
////    private OrderMapper shopOrderMapper;
    private static final String GATEWAY_URL = "https://openapi-sandbox.dl.alipaydev.com/gateway.do";
    private static final String FORMAT = "JSON";
    private static final String CHARSET = "utf-8";
    private static final String SIGN_TYPE = "RSA2";

    @Operation(summary = "支付")
    @SaIgnore
    @GetMapping("/alipay")// &subject=xxx&traceNo=xxx&totalAmount=xxx
    public void pay(@RequestParam String subject, @RequestParam String traceNo, @RequestParam String totalAmount, HttpServletResponse httpResponse) throws Exception {
        log.info("支付成功:{}", subject);
        AlipayClient alipayClient = new DefaultAlipayClient(GATEWAY_URL, aliPayConfig.getAppId(),
                aliPayConfig.getAppPrivateKey(), FORMAT, CHARSET, aliPayConfig.getAlipayPublicKey(), SIGN_TYPE);
        AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();
        request.setNotifyUrl(aliPayConfig.getNotifyUrl());
        request.setBizContent("{\"out_trade_no\":\"" + traceNo + "\","
                + "\"total_amount\":\"" + totalAmount + "\","
                + "\"subject\":\"" + subject + "\","
                + "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}");
        String form = "";
        try {
            // 调用SDK生成表单
            form = alipayClient.pageExecute(request).getBody();
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        httpResponse.setContentType("text/html;charset=" + CHARSET);
        // 直接将完整的表单html输出到页面
        httpResponse.getWriter().write(form);
        httpResponse.getWriter().flush();
        httpResponse.getWriter().close();
    }

    @Operation(summary = "手机支付")
    @SaIgnore
    @GetMapping("/alipay2")// &subject=xxx&traceNo=xxx&totalAmount=xxx
    public void pay2(@RequestParam String subject, @RequestParam String traceNo, @RequestParam String totalAmount, HttpServletResponse httpResponse) throws Exception {
        log.info("支付成功:{}", subject);
        AlipayClient alipayClient = new DefaultAlipayClient(GATEWAY_URL, aliPayConfig.getAppId(),
                aliPayConfig.getAppPrivateKey(), FORMAT, CHARSET, aliPayConfig.getAlipayPublicKey(), SIGN_TYPE);
        AlipayTradeWapPayRequest request = new AlipayTradeWapPayRequest();
        request.setNotifyUrl(aliPayConfig.getNotifyUrl());
        AlipayTradeWapPayModel model = new AlipayTradeWapPayModel();
        model.setOutTradeNo(traceNo);
        model.setTotalAmount(totalAmount);
        model.setSubject(subject);
//        model.setProductCode("QUICK_WAP_WAY");
//        model.setSellerId("2088102147948060");
        request.setBizModel(model);
        AlipayTradeWapPayResponse response = alipayClient.pageExecute(request, "POST");
        // 如果需要返回GET请求，请使用
        // AlipayTradeWapPayResponse response = alipayClient.pageExecute(request, "GET");
        String pageRedirectionData = response.getBody();
        System.out.println(pageRedirectionData);

        if (response.isSuccess()) {
            System.out.println("调用成功");
//            UpdateWrapper<BuyrOrder> objectUpdateWrapper = new UpdateWrapper<>();
//            LambdaUpdateWrapper<BuyrOrder> eq = objectUpdateWrapper.lambda().set(BuyrOrder::getOrderStatus, 1).eq(BuyrOrder::getId, traceNo);
//            buyrOrderService.update(eq);
            httpResponse.setContentType("text/html;charset=" + CHARSET);
            // 直接将完整的表单html输出到页面
            httpResponse.getWriter().write(pageRedirectionData);
            httpResponse.getWriter().flush();
            httpResponse.getWriter().close();
        } else {
            System.out.println("调用失败");
            // sdk版本是"4.38.0.ALL"及以上,可以参考下面的示例获取诊断链接
//             String diagnosisUrl = DiagnosisUtils.getDiagnosisUrl(response);
            // System.out.println(diagnosisUrl);
        }
    }

    @Operation(summary = "支付成功回调")
    @SaIgnore
    @PostMapping("/notify")  // 注意这里必须是POST接口
    public String payNotify(HttpServletRequest request) throws Exception {
        if (request.getParameter("trade_status").equals("TRADE_SUCCESS")) {
            System.out.println("=========支付宝异步回调========");

            Map<String, String> params = new HashMap<>();
            Map<String, String[]> requestParams = request.getParameterMap();
            for (String name : requestParams.keySet()) {
                params.put(name, request.getParameter(name));
                // System.out.println(name + " = " + request.getParameter(name));
            }

            String tradeNo = params.get("out_trade_no");
            String gmtPayment = params.get("gmt_payment");
            String alipayTradeNo = params.get("trade_no");
            UpdateWrapper<BuyrOrder> objectUpdateWrapper = new UpdateWrapper<>();
            LambdaUpdateWrapper<BuyrOrder> eq = objectUpdateWrapper.lambda().set(BuyrOrder::getOrderStatus, OrderStatusEnum.Dispatchinprogress).set(BuyrOrder::getPayMethod, "支付宝").eq(BuyrOrder::getId, tradeNo);
            buyrOrderService.update(eq);
            // 支付宝验签
            if (Factory.Payment.Common().verifyNotify(params)) {
                // 验签通过
                System.out.println("交易名称: " + params.get("subject"));
                System.out.println("交易状态: " + params.get("trade_status"));
                System.out.println("支付宝交易凭证号: " + params.get("trade_no"));
                System.out.println("商户订单号: " + params.get("out_trade_no"));
                System.out.println("交易金额: " + params.get("total_amount"));
                System.out.println("买家在支付宝唯一id: " + params.get("buyer_id"));
                System.out.println("买家付款时间: " + params.get("gmt_payment"));
                System.out.println("买家付款金额: " + params.get("buyer_pay_amount"));
                // 更新订单未已支付
//                Orders order = new Orders();
//                order.setId(Long.valueOf(tradeNo));
//                order.setStatus(2);
////                order.setCheckoutTime(params.get("gmt_payment"));
//                shopOrderMapper.updateById(order);
            }
        }
        return "success";
    }

    @SaIgnore
    @Operation(summary = "退款")
    @PostMapping("/refund")
    public Result refund(@RequestBody Apientity apientity) throws AlipayApiException, JsonProcessingException {
        log.info("退款参数:{}", apientity);
        Result refund = aliPayService.refund(apientity);
        log.info("退款结果:{}", refund);
        return Result.success(refund);
    }

    @Operation(summary = "获取交易详情信息")
    @SaIgnore
    @PostMapping("/getapliy")
    public Result getapliy(@RequestBody Apientity apientity) throws AlipayApiException, JsonProcessingException {
        AlipayResponse getapliy = aliPayService.getapliy(apientity);

        return Result.success(getapliy);

    }

    @Operation(summary = "获取退款详情信息")
    @SaIgnore
    @PostMapping("/RefundBillDetails")
    public Result refundBillDetails(@RequestBody Apientity apientity) throws AlipayApiException, JsonProcessingException {
        AlipayResponse alipayResponse = aliPayService.refundBillDetails(apientity);

        return Result.success(alipayResponse);
    }


    @Operation(summary = "所有的信心包含支付")
    @GetMapping("/cwMange")
    public Result cwMange() throws AlipayApiException, JsonProcessingException {


        List<BuyrOrder> list = buyrOrderService.list(Wrappers.<BuyrOrder>lambdaQuery().eq(BuyrOrder::getOrderStatus, 1));
        List<String> collect = list.stream().map(BuyrOrder::getId).collect(Collectors.toList());
        List<AlipayResponse> objects = new ArrayList<>();

        for (String s : collect) {
            Apientity apientity = new Apientity();

            apientity.setTraceNo(s);
            AlipayResponse getapliy = aliPayService.getapliy(apientity);
            objects.add(getapliy);

        }

//        List<AlipayResponse> objects3 = new ArrayList<>();
//        objects3.addAll(objects);
//        objects3.addAll(objects2);
//        aliPayService.getapliy(apientity);
        return Result.success(objects);
    }

    @Operation(summary = "搜索查询")
    @GetMapping("/tjSearch")
    public Result search(@RequestParam String orderId) throws AlipayApiException, JsonProcessingException {
        log.info("订单号：{}", orderId);
        BuyrOrder one = buyrOrderService.getOne(Wrappers.<BuyrOrder>lambdaQuery().eq(BuyrOrder::getOrderId, orderId));
        List<AlipayResponse> objects = new ArrayList<>();


        Apientity apientity = new Apientity();

        apientity.setTraceNo(one.getId());
        AlipayResponse getapliy = aliPayService.getapliy(apientity);
        objects.add(getapliy);
        return Result.success(objects);
    }
   @Operation(summary = "退款搜索查询")
    @GetMapping("/tktjSearch")
    public Result tksearch(@RequestParam String orderId) throws AlipayApiException, JsonProcessingException {
        log.info("订单号：{}", orderId);
        BuyrOrder one = buyrOrderService.getOne(Wrappers.<BuyrOrder>lambdaQuery().eq(BuyrOrder::getOrderId, orderId));
        List<AlipayResponse> objects = new ArrayList<>();


        Apientity apientity = new Apientity();

        apientity.setTraceNo(one.getId());
        AlipayResponse getapliy = aliPayService.getapliy(apientity);
        objects.add(getapliy);
        return Result.success(objects);
    }

    @Operation(summary = "所有的退款")
    @GetMapping("/cwMange2")

    public Result cwMange2() throws AlipayApiException, JsonProcessingException {


        List<BuyrOrder> list2 = buyrOrderService.list(Wrappers.<BuyrOrder>lambdaQuery().eq(BuyrOrder::getOrderStatus, 4));
        List<String> collect2 = list2.stream().map(BuyrOrder::getId).collect(Collectors.toList());
        log.info("嘻嘻：{}", list2);
        List<AlipayResponse> objects = new ArrayList<>();

        for (String s : collect2) {
            Apientity apientity = new Apientity();

            apientity.setTraceNo(s);

            AlipayResponse alipayResponse1 = aliPayService.refundBillDetails(apientity);
            objects.add(alipayResponse1);

        }
        return Result.success(objects);
    }
}
